package cn.demoncat.util.lang.entity;

import cn.demoncat.util.lang.*;
import cn.demoncat.util.lang.constant.StringConstant;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * 短信数据（请求参数/响应数据）
 * 
 * @author 延晓磊
 *
 * @since 2019年1月9日
 */
public class SmsData {

	/**
	 * 手机号码：多个用,分隔
	 *
	 * 云通讯 = 最多200个
	 * 阿里云 = 最多1000个
	 */
	private String phone;
	/**
	 * 手机号列表
	 */
	private Set<String> phones;
	/**
	 * 应用名称（发送人/短信签名，通过 app.name 配置 + AppProperties获取）
	 *
	 * 云通讯 = 日志标记发送人
	 * 阿里云 = 日志标记发送人，短信签名（需要审核）
	 * 卓望 = 日志标记发送人
	 */
	private String appName;
	/**
	 * 渠道的短信模板ID（对接渠道，发送短信）
	 * 
	 * 云通讯 = 81710 -- 你好{1}，您的验证码为{2}
	 * 阿里云 = SMS_0000 -- 你好${n1}，您的验证码为${n2}
	 * 卓望 = 12075859 -- 你好${2}，您的验证码为${3}
	 */
	private String template;
	/**
	 * 统一的短信模板ID（记录日志，便于跟踪）
	 *
	 * 统一模板 = [云通讯渠道模板,阿里云渠道模板……]
	 */
	private String templateId;
	/**
	 * 短信参数：["延晓磊","1234"]
	 * 
	 * 云通讯 = 转换为对应占位符序号的数组：["延晓磊","1234"]
	 * 阿里云 = 转换为对应占位符序号的MAP：{"n1":"延晓磊", "n2": "1234"}
	 * 卓望 = 转换为对应占位符序号的数组：["手机号|延晓磊|1234"]
	 */
	private String[] param;
	/**
	 * 短信参数字符串，用于保存参数、打印日志、查看记录
	 */
	private String paramText;
	/**
	 * 响应状态
	 * 
	 * 云通讯：000000 表示成功
	 * 阿里云：OK 表示成功
	 * 卓望：0000
	 */
	private String code;
	/**
	 * 响应消息
	 */
	private String message;
	/**
	 * 请求编号：标识同一批请求
	 * 
	 * 云通讯：自定义
	 * 阿里云：自定义
	 * 卓望：自定义
	 */
	private String requestId;
	/**
	 * 回执编号：服务端短信唯一标识符
	 * 
	 * 云通讯：成功返回sid
	 * 阿里云：用于短信发送状态查询，例 134523^4351232
	 * 卓望：成功返回msgid
	 */
	private String bizId;
	/**
	 * 是否为批量短信
	 */
	private Boolean isBatch;

	/**
	 * 短信参数
	 * 
	 * @param appName	应用名称（发送人/短信签名，通过 app.name 配置 + AppProperties获取）
	 * @param phone 	手机号码：多个用,分隔
	 * @param template	渠道的短信模板ID（发送短信）
	 * @param templateId	统一的短信模板ID （记录日志）
	 * @param param		短信参数
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年1月9日
	 */
	public SmsData(String appName, String phone, String template, String templateId, String... param) {
		super();
		this.phones = trimPhone(StringUtil.splitToSet(phone));
		this.phone = StringUtil.join(this.phones);
		this.appName = appName;
		this.template = template;
		this.templateId = templateId;
		this.param = param;
		this.paramText = ArrayUtils.isEmpty(param) ? StringConstant.EMPTY : StringUtil.join(param);
		this.isBatch = CollectionUtils.isNotEmpty(this.phones) && this.phones.size() > 1;
		this.requestId = IDUtil.getTime();
		this.bizId = StringConstant.EMPTY;
		this.code = StringConstant.EMPTY;
		this.message = StringConstant.EMPTY;
	}

	/**
	 * 短信参数
	 * 
	 * @param appName	应用名称（发送人/短信签名，通过 app.name 配置 + AppProperties获取）
	 * @param phone 	手机号码：多个用,分隔
	 * @param template	渠道的短信模板ID（发送短信）
	 * @param templateId	统一的短信模板ID （记录日志）
	 * @param param		短信参数
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年1月9日
	 */
	public SmsData(String appName, String[] phone, String template, String templateId, String... param) {
		super();
		this.phones = trimPhone(CollectionUtil.arrayToSet(phone));
		this.phone = StringUtil.join(this.phones);
		this.appName = appName;
		this.template = template;
		this.templateId = templateId;
		this.param = param;
		this.paramText = ArrayUtils.isEmpty(param) ? StringConstant.EMPTY : StringUtil.join(param);
		this.isBatch = CollectionUtils.isNotEmpty(this.phones) && this.phones.size() > 1;
		this.requestId = IDUtil.getTime();
		this.bizId = StringConstant.EMPTY;
		this.code = StringConstant.EMPTY;
		this.message = StringConstant.EMPTY;
	}

	/**
	 * 短信参数
	 * 
	 * @param appName	应用名称（发送人/短信签名，通过 app.name 配置 + AppProperties获取）
	 * @param phone 	手机号码：多个用,分隔
	 * @param template	渠道的短信模板ID（发送短信）
	 * @param templateId	统一的短信模板ID （记录日志）
	 * @param param		短信参数
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年1月9日
	 */
	public SmsData(String appName, Collection<String> phone, String template, String templateId, String... param) {
		super();
		this.phones = trimPhone(phone);
		this.phone = StringUtil.join(this.phones);
		this.appName = appName;
		this.template = template;
		this.templateId = templateId;
		this.param = param;
		this.paramText =  ArrayUtils.isEmpty(param) ? StringConstant.EMPTY : StringUtil.join(param);
		this.isBatch = CollectionUtils.isNotEmpty(this.phones) && this.phones.size() > 1;
		this.requestId = IDUtil.getTime();
		this.bizId = StringConstant.EMPTY;
		this.code = StringConstant.EMPTY;
		this.message = StringConstant.EMPTY;
	}

	/**
	 * 解析短信模板
	 * 
	 * @param template	模板内容（各平台的模板内容保存时应统一格式，申请模板时区分）："你好{1}，您的验证码为{2}"
	 * @param param		模板参数（各平台的模板参数保存时应统一格式，发送短信时区分）："延晓磊,1234"
	 * 
	 * @return 解析结果：你好延晓磊，您的验证码为1234
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年1月9日
	 */
	public static String parse(String template, String param) {
		return ElUtil.parseNl(template, StringUtil.split(param));
	}

	/**
	 * 去重，校验手机号
	 * 
	 * @param phones
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年8月16日
	 */
	public static Set<String> trimPhone(Collection<String> phones){
		// 非空
		if (CollectionUtils.isNotEmpty(phones)) {
			// 去重，去空，去非法
			Set<String> list = new HashSet<>();
			for (String str : phones) {
				if (StringUtils.isNotBlank(str) && ParamValidUtil.isMobile(str)) {
					list.add(str);
				}
			}
			if (!list.isEmpty()) {
				return list;
			}
		}
		return null;
	}
	
	
	/**
	 * 手机号码：多个用,分隔
	 */
	public String getPhone() {
		return phone;
	}

	/**
	 * 手机号码：多个用,分隔，同时设置phones
	 */
	public void setPhone(String phone) {
		this.phones = trimPhone(StringUtil.splitToSet(phone));
		this.phone = StringUtil.join(this.phones);
	}

	/**
	 * 应用名称（发送人/短信签名，通过 app.name 配置 + AppProperties获取）
	 */
	public String getAppName() {
		return appName;
	}
	/**
	 * 应用名称（发送人/短信签名，通过 app.name 配置 + AppProperties获取）
	 */
	public void setAppName(String appName) {
		this.appName = appName;
	}

	/**
	 * 渠道的短信模板编号（对接渠道，发送短信）
	 */
	public String getTemplate() {
		return template;
	}

	public void setTemplate(String template) {
		this.template = template;
	}

	/**
	 * 统一的短信模板编号（记录日志，便于跟踪）
	 */
	public String getTemplateId() {
		return templateId;
	}

	public void setTemplateId(String templateId) {
		this.templateId = templateId;
	}

	/**
	 * 短信参数：例 - ["延晓磊","1234"]
	 */
	public String[] getParam() {
		return param;
	}

	public void setParam(String[] param) {
		this.param = param;
	}

	/**
	 * 短信参数字符串：例 - "延晓磊,1234"
	 */
	public String getParamText() {
		return this.paramText;
	}

	public void setParamText(String paramText) {
		this.paramText = paramText;
	}

	/**
	 * 响应状态
	 */
	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	/**
	 * 响应消息
	 */
	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	/**
	 * 请求编号
	 */
	public String getRequestId() {
		return requestId;
	}

	public void setRequestId(String requestId) {
		this.requestId = requestId;
	}

	/**
	 * 回执编号
	 */
	public String getBizId() {
		return bizId;
	}

	public void setBizId(String bizId) {
		this.bizId = bizId;
	}

	/**
	 * 是否为批量短信
	 */
	public Boolean getIsBatch() {
		return isBatch;
	}

	public void setIsBatch(Boolean isBatch) {
		this.isBatch = isBatch;
	}

	/**
	 * 手机号列表
	 */
	public Set<String> getPhones() {
		return phones;
	}

	/**
	 * 手机号列表，同时设置phone
	 */
	public void setPhones(Set<String> phones) {
		this.phones = trimPhone(phones);
		this.phone = StringUtil.join(this.phones);
	}

}
